#!/usr/bin/env python3
"""
BoLe HR系统全面测试脚本
生成大量测试问题，验证系统功能和实时状态显示
"""

import asyncio
import requests
import json
import time
import random
from datetime import datetime
from concurrent.futures import ThreadPoolExecutor
import sys

class HRSystemTester:
    def __init__(self, base_url="http://localhost:8089"):
        self.base_url = base_url
        self.api_url = f"{base_url}/api"
        self.success_count = 0
        self.error_count = 0
        self.total_tests = 0
        self.test_results = []
        
    def generate_test_questions(self):
        """生成大量测试问题"""
        test_questions = [
            # 基础搜索类问题
            "筛选Python工程师",
            "找几个Python开发者",
            "搜索5年以上经验的候选人", 
            "查找高级Python工程师",
            "筛选有机器学习经验的候选人",
            "找一些数据科学家",
            "搜索全栈开发工程师",
            "查找前端开发人员",
            "筛选后端工程师",
            "找几个DevOps工程师",
            
            # 技能相关问题
            "找擅长Django的开发者",
            "搜索会Flask的工程师",
            "筛选精通React的候选人",
            "查找Vue.js开发者",
            "找会Node.js的工程师",
            "搜索数据库专家",
            "筛选云计算工程师",
            "查找AI算法工程师",
            "找深度学习专家",
            "搜索NLP工程师",
            
            # 经验级别问题
            "找3-5年经验的工程师",
            "搜索资深开发者",
            "筛选初级程序员",
            "查找10年以上经验的专家",
            "找有创业经验的候选人",
            "搜索大厂背景的工程师",
            "筛选有团队管理经验的候选人",
            "查找技术负责人",
            "找架构师级别的候选人",
            "搜索CTO级别人才",
            
            # 地域和薪资问题
            "找北京的Python工程师",
            "搜索上海地区的开发者",
            "筛选深圳的候选人",
            "查找杭州的工程师",
            "找远程工作的开发者",
            "搜索期望薪资30K+的候选人",
            "筛选薪资面议的工程师",
            "查找高薪候选人",
            "找性价比高的开发者",
            "搜索应届毕业生",
            
            # 复杂综合问题
            "找几个在北京有5年以上Python经验的高级工程师",
            "搜索擅长机器学习且有大厂背景的算法专家",
            "筛选精通前后端开发的全栈工程师",
            "查找有创业经验的技术合伙人",
            "找会Python和Go的云原生工程师",
            "搜索有AI项目经验的资深开发者",
            "筛选能独立带团队的技术负责人",
            "查找有开源贡献的优秀工程师",
            "找具备架构设计能力的高级专家",
            "搜索有国际化项目经验的开发者",
            
            # 简单问候和功能测试
            "你好",
            "系统功能介绍",
            "帮我分析一下候选人质量",
            "生成一份招聘报告",
            "显示所有候选人",
            "系统状态如何",
            "刷新数据",
            "清空缓存",
            "重新加载",
            "退出系统",
        ]
        
        # 添加一些随机变化
        variations = [
            "帮我{}",
            "能否{}",
            "请{}", 
            "我需要{}",
            "协助{}",
        ]
        
        expanded_questions = test_questions.copy()
        for question in test_questions[:20]:  # 只对前20个问题添加变化
            for variation in random.sample(variations, 2):
                expanded_questions.append(variation.format(question))
        
        return expanded_questions

    def test_single_question(self, question, test_id):
        """测试单个问题"""
        start_time = time.time()
        try:
            print(f"[{test_id:03d}] 测试问题: {question[:50]}...")
            
            response = requests.post(
                f"{self.api_url}/chat",
                json={"message": question},
                headers={"Content-Type": "application/json"},
                timeout=30
            )
            
            processing_time = time.time() - start_time
            
            if response.status_code == 200:
                result = response.json()
                if result.get("success", False):
                    self.success_count += 1
                    print(f"[{test_id:03d}] ✅ 成功 ({processing_time:.2f}s)")
                    return {
                        "test_id": test_id,
                        "question": question,
                        "status": "success",
                        "processing_time": processing_time,
                        "response_preview": result.get("message", "")[:100]
                    }
                else:
                    self.error_count += 1
                    error_msg = result.get("error", "未知错误")
                    print(f"[{test_id:03d}] ❌ API错误: {error_msg}")
                    return {
                        "test_id": test_id,
                        "question": question,
                        "status": "api_error",
                        "error": error_msg,
                        "processing_time": processing_time
                    }
            else:
                self.error_count += 1
                print(f"[{test_id:03d}] ❌ HTTP错误: {response.status_code}")
                return {
                    "test_id": test_id,
                    "question": question,
                    "status": "http_error",
                    "http_code": response.status_code,
                    "processing_time": processing_time
                }
                
        except requests.exceptions.Timeout:
            self.error_count += 1
            print(f"[{test_id:03d}] ⏰ 超时")
            return {
                "test_id": test_id,
                "question": question,
                "status": "timeout",
                "processing_time": time.time() - start_time
            }
        except Exception as e:
            self.error_count += 1
            print(f"[{test_id:03d}] 💥 异常: {str(e)}")
            return {
                "test_id": test_id,
                "question": question,
                "status": "exception",
                "error": str(e),
                "processing_time": time.time() - start_time
            }

    def run_sequential_test(self, questions):
        """顺序测试"""
        print(f"\n🔄 开始顺序测试 {len(questions)} 个问题...")
        
        for i, question in enumerate(questions, 1):
            result = self.test_single_question(question, i)
            self.test_results.append(result)
            self.total_tests += 1
            
            # 每5个测试暂停1秒，避免服务器过载
            if i % 5 == 0:
                time.sleep(1)
                
        print(f"\n✅ 顺序测试完成")

    def run_parallel_test(self, questions, max_workers=3):
        """并行测试（控制并发数量）"""
        print(f"\n🚀 开始并行测试 {len(questions)} 个问题 (最大并发: {max_workers})...")
        
        with ThreadPoolExecutor(max_workers=max_workers) as executor:
            # 提交所有测试任务
            future_to_question = {
                executor.submit(self.test_single_question, question, i): (question, i) 
                for i, question in enumerate(questions, 1)
            }
            
            # 收集结果
            for future in future_to_question:
                result = future.result()
                self.test_results.append(result)
                self.total_tests += 1
                
        print(f"\n✅ 并行测试完成")

    def generate_report(self):
        """生成测试报告"""
        print(f"\n" + "="*60)
        print(f"📊 BoLe HR系统测试报告")
        print(f"="*60)
        print(f"测试时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
        print(f"总测试数: {self.total_tests}")
        print(f"成功数量: {self.success_count} ({self.success_count/self.total_tests*100:.1f}%)")
        print(f"失败数量: {self.error_count} ({self.error_count/self.total_tests*100:.1f}%)")
        
        # 按状态分类统计
        status_counts = {}
        processing_times = []
        
        for result in self.test_results:
            status = result["status"]
            status_counts[status] = status_counts.get(status, 0) + 1
            if "processing_time" in result:
                processing_times.append(result["processing_time"])
        
        print(f"\n📈 详细统计:")
        for status, count in status_counts.items():
            print(f"  {status}: {count} ({count/self.total_tests*100:.1f}%)")
        
        if processing_times:
            avg_time = sum(processing_times) / len(processing_times)
            max_time = max(processing_times)
            min_time = min(processing_times)
            print(f"\n⏱️  处理时间:")
            print(f"  平均: {avg_time:.2f}s")
            print(f"  最大: {max_time:.2f}s")
            print(f"  最小: {min_time:.2f}s")
        
        # 显示失败的测试
        failed_tests = [r for r in self.test_results if r["status"] != "success"]
        if failed_tests:
            print(f"\n❌ 失败的测试 ({len(failed_tests)}个):")
            for result in failed_tests[:10]:  # 只显示前10个
                print(f"  [{result['test_id']:03d}] {result['question'][:40]}... - {result['status']}")
                if 'error' in result:
                    print(f"       错误: {result['error'][:60]}...")
        
        print(f"\n" + "="*60)
        
        # 保存详细报告到文件
        report_file = f"test_report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
        with open(report_file, 'w', encoding='utf-8') as f:
            json.dump({
                "summary": {
                    "total_tests": self.total_tests,
                    "success_count": self.success_count,
                    "error_count": self.error_count,
                    "success_rate": self.success_count/self.total_tests*100 if self.total_tests > 0 else 0
                },
                "details": self.test_results
            }, f, ensure_ascii=False, indent=2)
        
        print(f"📄 详细报告已保存至: {report_file}")

def main():
    print("🚀 BoLe HR系统全面测试开始")
    print("="*60)
    
    # 检查服务器状态
    tester = HRSystemTester()
    try:
        response = requests.get(f"{tester.api_url}/hr/overview", timeout=5)
        if response.status_code != 200:
            print("❌ 服务器未正常响应，请检查hr_system.py是否在运行")
            return
    except Exception as e:
        print(f"❌ 无法连接到服务器: {e}")
        print("请确保hr_system.py在localhost:8089上运行")
        return
    
    print("✅ 服务器连接正常")
    
    # 生成测试问题
    questions = tester.generate_test_questions()
    print(f"📝 生成了 {len(questions)} 个测试问题")
    
    # 选择测试模式
    if len(sys.argv) > 1 and sys.argv[1] == "--quick":
        # 快速测试模式，只测试前20个问题
        questions = questions[:20]
        print(f"🏃 快速测试模式，测试 {len(questions)} 个问题")
        tester.run_sequential_test(questions)
    elif len(sys.argv) > 1 and sys.argv[1] == "--parallel":
        # 并行测试模式
        tester.run_parallel_test(questions[:30], max_workers=3)
    else:
        # 默认完整测试
        print("🔄 完整测试模式")
        tester.run_sequential_test(questions)
    
    # 生成报告
    tester.generate_report()

if __name__ == "__main__":
    main()



